package com.recharge.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.hash.HashCode;
import com.recharge.common.domain.PageDO;
import com.recharge.common.enums.ErrorCode;
import com.recharge.common.result.ResultDO;
import com.recharge.common.result.ResultSupport;
import com.recharge.common.util.BeanUtilsExtends;
import com.recharge.common.util.http.MapTool;
import com.recharge.core.entity.ReportOrderGoodsStatisEntity;
import com.recharge.core.entity.ReportProviderStatisEntity;
import com.recharge.core.mapper.ReportProviderStatisMapper;
import com.recharge.domain.query.ReportProviderStatisQueryDO;
import com.recharge.domain.vo.ReportOrderGoodsStatisDO;
import com.recharge.domain.vo.ReportProviderStatisDO;
import com.recharge.service.ReportProviderStatisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.stream.Collectors;


@Service
public class ReportProviderStatisServiceImpl extends ServiceImpl<ReportProviderStatisMapper, ReportProviderStatisEntity> implements ReportProviderStatisService {

    private Logger logger = LoggerFactory.getLogger(this.getClass().getName());

    @Autowired
    private ReportProviderStatisMapper reportProviderStatisMapper;

    @Override
    public ResultDO add(ReportProviderStatisDO domain) {
        return null;
    }

    @Override
    public ResultDO addForList(List<ReportProviderStatisEntity> dolist) {
        if(dolist != null && dolist.size()>0){
            this.saveBatch(dolist);
        }
        System.out.println("添加结束");
        return null;
    }

    @Override
    public ResultDO get(String id) {

        ResultDO result = new ResultSupport();
        ReportProviderStatisEntity entity = null;
        try {
            entity = this.getById(id);
        }catch (Exception e){
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }
        ReportProviderStatisDO domain = getDomain(entity);
        result.setModel(ResultDO.FIRST_MODEL_KEY, domain);
        return result;
    }

    @Override
    public ResultDO find(ReportProviderStatisQueryDO query) {
        return null;
    }

    @Override
    public ResultDO taskReport(){
        logger.debug( " 当前线程名称：" + Thread.currentThread().getName());
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i=0;i<30;i++){
            try {
                calendar.set(Calendar.DATE,calendar.get(Calendar.DATE)-1);
                Date nowDa = sdf.parse(calendar.get(Calendar.YEAR)+"-"+(calendar.get(Calendar.MONTH)+1)+"-"+calendar.get(Calendar.DATE));
                QueryWrapper<ReportProviderStatisEntity> wrapper = new QueryWrapper<>();
                wrapper.lambda().eq(ReportProviderStatisEntity::getDayDate,nowDa);
                Integer count = baseMapper.selectCount(wrapper);
                if(count==null||(count!=null&&count==0)){
                    taskReportByDate(nowDa);
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return null;
    }

    private void taskReportByDate(Date nowDa){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime  = LocalDateTime.ofInstant(Instant.ofEpochMilli(nowDa.getTime()), ZoneId.systemDefault());
        LocalDateTime startTime = localDateTime.with(LocalTime.MIN);
        LocalDateTime entTime = localDateTime.with(LocalTime.MAX);
        Date todayStartDa = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant());
        Date todayEndDa = Date.from(entTime.atZone(ZoneId.systemDefault()).toInstant());

        String start = sdf.format(todayStartDa);
        String end = sdf.format(todayEndDa);

        Map<String,Object> reportparam = new HashMap<>();
        reportparam.put("beginDate",start);
        reportparam.put("endDate",end);
        System.out.println("统计供应单,统计供应单时间范围："+start+"到"+end);
        List<Map<String,Object>> totalmap = reportProviderStatisMapper.reportProviderOrderTotalAll(reportparam);
        Integer total = ((Long)totalmap.get(0).get("total")).intValue();
        System.out.println(start+"到"+end+"总数："+total);
        Integer reportcount = total%10000==0?total/10000:(total/10000)+1;

        Map<Integer,Object> rateThree = new HashMap<>();
        Map<Integer,Object> rateTen = new HashMap<>();
        Map<Integer,Object> rateThirty = new HashMap<>();
        Map<Integer,Object> avgRateThree = new HashMap<>();
        Map<Integer,Object> avgRateTen = new HashMap<>();
        Map<Integer,Object> avgRateThirty = new HashMap<>();
        Map<Integer,Object> totallist = new HashMap<>();
        reportparam.put("timeSpace",3);
        List<Map<String,Object>> RateSpaceTotal = reportProviderStatisMapper.reportProviderOrderRateSpaceTotal(reportparam);
        Integer rateTotal = ((Long)RateSpaceTotal.get(0).get("total")).intValue();

        Integer rateCount = rateTotal%10000==0?rateTotal/10000:(rateTotal/10000)+1;
        for(int index=0;index<rateCount;index++) {
            try {
                Map<String,Object> spaceParam = new HashMap<>();
                spaceParam.put("beginDate",start);
                spaceParam.put("endDate",end);
                spaceParam.put("timeSpace","3");
                spaceParam.put("beginIndex", index * 10000);
                spaceParam.put("endIndex", 10000);
                //统计每三分钟供货单成功量
                List<Map<String,Object>> ProviderRateThreeNum = reportProviderStatisMapper.reportProviderOrderRateBySpace(spaceParam);
                //统计每三分钟订单总数
                List<Map<String,Object>> orderRateThreeNum = reportProviderStatisMapper.reportOrderRateBySpace(spaceParam);

                //将商品ID 代理商ID 供货商ID 时间拼接成串转成hashcode存为键 转存进map
                ProviderRateThreeNum.forEach(m->{
                    if(m.get("goods_id")!=null&&m.get("merchant_id")!=null&&m.get("provider_id")!=null&&m.get("time")!=null){
                        rateThree.put(fetchRateKey(m),m);
                    }
                });
                //将订单拼接转hashcode判断map内是否存在 如果存在则计算成功率存入map
                orderRateThreeNum.forEach(m->{
                    if(m.get("goods_id")!=null&&m.get("merchant_id")!=null&&m.get("provider_id")!=null&&m.get("time")!=null){
                        Integer rateHashCode = fetchRateKey(m);
                        if(rateThree.containsKey(rateHashCode)){
                            Map<String,Object> map = (Map<String,Object>)rateThree.get(rateHashCode);
                            Double sucess=Double.valueOf(map.get("success_rate_num").toString());
                            Long totalnum =(Long) m.get("num");
                            Double sucessRate = sucess/totalnum.doubleValue();
                            map.put("threeSucessRate",sucessRate);
                            rateThree.remove(rateHashCode);
                            rateThree.put(rateHashCode,map);
                        }
                    }
                });

//                orderRateThreeNum.stream().map(m->{
//
//                }).collect(Collectors.toList());

                spaceParam.put("timeSpace","10");
                List<Map<String,Object>> ProviderRateTenNum = reportProviderStatisMapper.reportProviderOrderRateBySpace(spaceParam);
                List<Map<String,Object>> orderRateTenNum = reportProviderStatisMapper.reportOrderRateBySpace(spaceParam);

                ProviderRateTenNum.forEach(m->{
                    if(m.get("goods_id")!=null&&m.get("merchant_id")!=null&&m.get("provider_id")!=null&&m.get("time")!=null){
                        rateTen.put(fetchRateKey(m),m);
                    }
                });

                orderRateTenNum.forEach(m->{
                    if(m.get("goods_id")!=null&&m.get("merchant_id")!=null&&m.get("provider_id")!=null&&m.get("time")!=null){
                        Integer rateHashCode = fetchRateKey(m);
                        if(rateTen.containsKey(rateHashCode)){
                            Map<String,Object> map = (Map<String,Object>)rateTen.get(rateHashCode);
                            Double sucess=Double.valueOf(map.get("success_rate_num").toString());
                            Long totalnum =(Long) m.get("num");
                            Double sucessRate = sucess/totalnum.doubleValue();
                            map.put("tenSucessRate",sucessRate);
                            rateTen.remove(rateHashCode);
                            rateTen.put(rateHashCode,map);
                        }
                    }
                });

                spaceParam.put("timeSpace","30");
                List<Map<String,Object>> ProviderRateThirtyNum = reportProviderStatisMapper.reportProviderOrderRateBySpace(spaceParam);
                List<Map<String,Object>> orderRateThirtyNum = reportProviderStatisMapper.reportOrderRateBySpace(spaceParam);

                ProviderRateThirtyNum.forEach(m->{
                    if(m.get("goods_id")!=null&&m.get("merchant_id")!=null&&m.get("provider_id")!=null&&m.get("time")!=null){
                        rateThirty.put(fetchRateKey(m),m);
                    }
                });

                orderRateThirtyNum.forEach(m->{
                    if(m.get("goods_id")!=null&&m.get("merchant_id")!=null&&m.get("provider_id")!=null&&m.get("time")!=null){
                        Integer rateHashCode = fetchRateKey(m);
                        if(rateThirty.containsKey(rateHashCode)){
                            Map<String,Object> map = (Map<String,Object>)rateThirty.get(rateHashCode);
                            Double sucess=Double.valueOf(map.get("success_rate_num").toString());
                            Long totalnum =(Long) m.get("num");
                            Double sucessRate = sucess/totalnum.doubleValue();
                            map.put("thirtySucessRate",sucessRate);
                            rateThirty.remove(rateHashCode);
                            rateThirty.put(rateHashCode,map);
                        }
                    }
                });

            }catch (Exception e){
                e.printStackTrace();
            }

        }

        Map<String,Object> param = new HashMap<>();
        List<Map<String,Object>> orderCount = reportProviderStatisMapper.reportOrderTotalAllCount(reportparam);
        Integer orderTotal = ((Long)orderCount.get(0).get("total")).intValue();

        Integer orderCount2 = orderTotal%10000==0?orderTotal/10000:(orderTotal/10000)+1;
        for(int index=0;index<orderCount2;index++) {
            reportparam.put("beginIndex", index * 10000);
            reportparam.put("endIndex", 10000);
            List<Map<String,Object>> dolist = reportProviderStatisMapper.reportOrderTotalAll(reportparam);

            dolist.forEach(m->{
                String mkey = m.get("goods_id").toString()+m.get("merchant_id").toString()+m.get("provider_id").toString();
                totallist.put(mkey.hashCode(),m.get("num"));
            });
        }


        //rateThree.values().stream().collect(Collectors.groupingBy(e->fetchGroupKey((Map<String,Object>)e))).values().stream().collect(Collectors.averagingDouble(e->fetchAvg((Map<String,Object>)e)));
        //计算平均成功率(新)
        Map<Object,List<Object>> tempmap = rateThree.values().stream().collect(Collectors.groupingBy(e->fetchGroupKey((Map<String,Object>)e)));
        tempmap.keySet().forEach(m->{
            Double avgRate = tempmap.get(m).stream().collect(Collectors.averagingDouble(e->fetchAvg((Map<String,Object>)e,"threeSucessRate")));
            Map<String,Object> avgRateMap = new HashMap<>();
            avgRateMap.put("avgThreeSucessRate",avgRate);
            avgRateThree.put((Integer) m,avgRateMap);
        });
        Map<Object,List<Object>> tempmap2 = rateTen.values().stream().collect(Collectors.groupingBy(e->fetchGroupKey((Map<String,Object>)e)));
        tempmap2.keySet().forEach(m->{
            Double avgRate = tempmap2.get(m).stream().collect(Collectors.averagingDouble(e->fetchAvg((Map<String,Object>)e,"tenSucessRate")));
            Map<String,Object> avgRateMap = new HashMap<>();
            avgRateMap.put("avgTenSucessRate",avgRate);
            avgRateTen.put((Integer) m,avgRateMap);
        });
        Map<Object,List<Object>> tempmap3 = rateThirty.values().stream().collect(Collectors.groupingBy(e->fetchGroupKey((Map<String,Object>)e)));
        tempmap3.keySet().forEach(m->{
            Double avgRate = tempmap3.get(m).stream().collect(Collectors.averagingDouble(e->fetchAvg((Map<String,Object>)e,"thirtySucessRate")));
            Map<String,Object> avgRateMap = new HashMap<>();
            avgRateMap.put("avgThirtySucessRate",avgRate);
            avgRateThirty.put((Integer) m,avgRateMap);
        });
        //循环map 根据商品、代理商、供应商ID转hashcode为键 计算平均成功率存入新map(旧)
        /*rateThree.keySet().forEach(m->{
            Map<String,Object> map=(Map<String,Object>)rateThree.get(m);
            String mkey = map.get("goods_id").toString()+map.get("merchant_id").toString()+map.get("provider_id").toString();
            if(avgRateThree.containsKey(mkey.hashCode())){
                Map<String,Object> p = (Map<String,Object>)avgRateThree.get(mkey.hashCode());
                Double threeSucessRate=p.get("threeSucessRate")==null?0.0:(Double) p.get("threeSucessRate");
                int count = (int)p.get("count");
                if(map.get("threeSucessRate")!=null){
                    threeSucessRate=threeSucessRate+(Double) map.get("threeSucessRate");
                }
                count++;
                p.put("threeSucessRate",threeSucessRate);
                p.put("count",count);
                p.put("avgThreeSucessRate",threeSucessRate/count);
                avgRateThree.remove(mkey.hashCode());
                avgRateThree.put(mkey.hashCode(),p);
            }else{
                map.put("count",1);
                map.put("avgThreeSucessRate",map.get("threeSucessRate"));
                avgRateThree.put(mkey.hashCode(),map);
            }
        });
        rateTen.keySet().forEach(m->{
            Map<String,Object> map=(Map<String,Object>)rateTen.get(m);
            String mkey = map.get("goods_id").toString()+map.get("merchant_id").toString()+map.get("provider_id").toString();
            if(avgRateTen.containsKey(mkey.hashCode())){
                Map<String,Object> p = (Map<String,Object>)avgRateTen.get(mkey.hashCode());
                Double tenSucessRate =p.get("tenSucessRate")==null?0.0:(Double) p.get("tenSucessRate");

                int count = (int)p.get("count");
                if(map.get("tenSucessRate")!=null){
                    tenSucessRate=tenSucessRate+(Double) map.get("tenSucessRate");
                }
                count++;
                p.put("tenSucessRate",tenSucessRate);
                p.put("count",count);
                p.put("avgTenSucessRate",tenSucessRate/count);
                avgRateTen.remove(mkey.hashCode());
                avgRateTen.put(mkey.hashCode(),p);
            }else{
                map.put("count",1);
                map.put("avgTenSucessRate",map.get("tenSucessRate"));
                avgRateTen.put(mkey.hashCode(),map);
            }
        });
        rateThirty.keySet().forEach(m->{
            Map<String,Object> map=(Map<String,Object>)rateThirty.get(m);
            String mkey = map.get("goods_id").toString()+map.get("merchant_id").toString()+map.get("provider_id").toString();
            if(avgRateThirty.containsKey(mkey.hashCode())){
                Map<String,Object> p = (Map<String,Object>)avgRateThirty.get(mkey.hashCode());
                Double thirtySucessRate=null;

                thirtySucessRate =p.get("thirtySucessRate")==null?0.0:(Double) p.get("thirtySucessRate");
                int count = (int)p.get("count");
                if(map.get("thirtySucessRate")!=null){
                    thirtySucessRate=thirtySucessRate+(Double) map.get("thirtySucessRate");
                }

                count++;
                p.put("thirtySucessRate",thirtySucessRate);
                p.put("count",count);
                p.put("avgThirtySucessRate",thirtySucessRate/count);
                avgRateThirty.remove(mkey.hashCode());
                avgRateThirty.put(mkey.hashCode(),p);
            }else{
                map.put("count",1);
                map.put("avgThirtySucessRate",map.get("thirtySucessRate"));
                avgRateThirty.put(mkey.hashCode(),map);
            }
        });*/

        for(int index=0;index<reportcount;index++) {

            reportparam.put("beginIndex", index * 10000);
            reportparam.put("endIndex", 10000);
            List<ReportProviderStatisEntity> list = reportProviderStatisMapper.taskReport(reportparam);
            list = list.stream().map(m->{
                String mkey = m.getGoodsId()+m.getMerchantId()+m.getProviderId();
                Long totalnum = (Long) totallist.get(mkey.hashCode());
                if(totalnum != null){
                    m.setSuccessRate(m.getSuccessNumber()/totalnum.doubleValue());
                    m.setTotalNumber(totalnum.intValue());
                }else{
                    m.setSuccessRate(0.0);
                    m.setTotalNumber(0);
                }
                Map<String,Object> threeMap = (Map<String,Object>)avgRateThree.get(mkey.hashCode());
                m.setSuccessRateThree((Double) threeMap.get("avgThreeSucessRate"));
                Map<String,Object> tenMap = (Map<String,Object>)avgRateTen.get(mkey.hashCode());
                m.setSuccessRateTen((Double) tenMap.get("avgTenSucessRate"));
                Map<String,Object> thirtymap = (Map<String,Object>)avgRateThirty.get(mkey.hashCode());
                m.setSuccessRateThirty((Double) thirtymap.get("avgThirtySucessRate"));
                m.setDayDate(nowDa);
                return m;
            }).collect(Collectors.toList());
            addForList(list);
        }
    }

    private int fetchGroupKey(Map<String,Object> map){
        String mkey = map.get("goods_id").toString()+map.get("merchant_id").toString()+map.get("provider_id").toString();
        return mkey.hashCode();
    }

    private int fetchRateKey(Map<String,Object> map){
        String mkey = map.get("goods_id").toString()+map.get("merchant_id").toString()+map.get("provider_id").toString()+map.get("time").toString();
        return mkey.hashCode();
    }

    private Double fetchAvg(Map<String,Object> map,String field){
        if(map.get(field)!=null){
            return (Double) map.get(field);
        }else{
            return 0.0;
        }
    }

    @Override
    public ResultDO reportOrder(ReportProviderStatisQueryDO query) {
        ResultDO result = new ResultSupport();
        Page<Map<String,String>> page = new Page<>(query.getCurrentPage(),query.getPageSize());
        IPage<Map<String,Object>> iPage =null;

        Map<String,Object> param = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //根据时间范围筛选
        try {
            if(query.getStartTime() != null){
                param.put("beginDate",query.getStartTime());
            }
            if(query.getEndTime() != null){
                param.put("endDate",query.getEndTime());
            }
        }catch (Exception e){
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        if(query.getTime() != null){
            param.put("dayDate",query.getTime());
        }
        //根据字段分组
        if(query.getType()!=null && !query.getType().equals("")){
            //根据商品组
            if(query.getType().equals("goodsGroup")){
                param.put("type","goods_group_id");
            }
            //根据商品
            if(query.getType().equals("goods")){
                param.put("type","goods_id");
            }
            //根据代理商
            if(query.getType().equals("merchant")){
                param.put("type","merchant_id");
            }
            //根据供应商
            if(query.getType().equals("provider")){
                param.put("type","provider_id");
            }
        }

        //排序顺序 降序、升序
        if(query.getOrder() != null){
            param.put("order",query.getOrder());
        }
        //排序字段
        if(query.getSortField() != null){
            if(query.getSortField().equals("successNumber")||query.getSortField().equals("failNumber")||query.getSortField().equals("processNumber")||query.getSortField().equals("unconfirmedNumber")||
                    query.getSortField().equals("totalNumber")||query.getSortField().equals("successRate")||query.getSortField().equals("denomination")||query.getSortField().equals("amount")||
                    query.getSortField().equals("cost")||query.getSortField().equals("profit")||query.getSortField().equals("successRateThree")||query.getSortField().equals("successRateTen")||
                    query.getSortField().equals("successRateThirty")||query.getSortField().equals("title")||query.getSortField().equals("averageSuccessTime")||query.getSortField().equals("averageResponseTime")||
                    query.getSortField().equals("fiveSecondFailed")
            ){
                param.put("sortField",query.getSortField());
            }

        }
        //10-20新增筛选
        //根据代理商筛选
        if(query.getMerchantId()!=null && !query.getMerchantId().equals("")){
            param.put("merchantId",query.getMerchantId());
        }
        //根据供货商筛选
        if(query.getProviderId()!=null && !query.getProviderId().equals("")){
            param.put("providerId",query.getProviderId());
        }
        //根据业务类型筛选
        if(query.getGroupType()!=null && !query.getGroupType().equals("")){
            param.put("groupType",query.getGroupType());
        }
        //根据业务类别筛选
        if(query.getBusinessClass()!=null && !query.getBusinessClass().equals("")){
            param.put("businessClass",query.getBusinessClass());
        }
        //根据供货方式筛选
        if(query.getBusinessType()!=null && !query.getBusinessType().equals("")){
            param.put("businessType",query.getBusinessType());
        }
        //根据供应单状态筛选
        if(query.getStatus()!=null && !query.getStatus().equals("")){
            param.put("status",query.getStatus());
        }

        List<Map<String, Object>> list = null;
        List<Map<String,Object>> totallist=null;

        try {
            //判断时间是否为当天
            if(query.getStartTime() != null){
                Date queryStatrtDa = sdf.parse(query.getStartTime());
                Date queryEndDa = sdf.parse(query.getEndTime());
                Date nowDa = new Date();
                LocalDateTime localDateTime  = LocalDateTime.ofInstant(Instant.ofEpochMilli(nowDa.getTime()), ZoneId.systemDefault());
                LocalDateTime startTime = localDateTime.with(LocalTime.MIN);
                LocalDateTime entTime = localDateTime.with(LocalTime.MAX);
                Date todayStartDa = Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant());
                Date todayEndDa = Date.from(entTime.atZone(ZoneId.systemDefault()).toInstant());
//              原判断选择日期是否在当天范围
//               if((todayStartDa.compareTo(queryStatrtDa)==-1||todayStartDa.compareTo(queryStatrtDa)==0)&&(queryEndDa.compareTo(todayEndDa)==-1||queryEndDa.compareTo(todayEndDa)==0)){
//                if(queryStatrtDa.compareTo(new Date())==-1&&(new Date()).compareTo(queryEndDa)==-1){

                if(
                (queryStatrtDa.compareTo(todayEndDa)==-1 || queryStatrtDa.compareTo(todayEndDa)==0)&&(todayStartDa.compareTo(queryEndDa)==-1||(todayStartDa.compareTo(queryEndDa)==0))
                ||(query.getSortField()!=null&&(query.getSortField().equals("successRate")||query.getSortField().equals("totalNumber")))
                ){
                    list = reportProviderStatisMapper.taskReportForToDay(param);
//                    if(query.getSortField()!=null&&(query.getSortField().equals("successRate")||query.getSortField().equals("totalNumber"))){
//
//                    }else{
//                        iPage = reportProviderStatisMapper.taskReportForToDay(page,param);
//                    }
                }else{
                    iPage = reportProviderStatisMapper.reportOrderList(page,param);
                }
            }else{
                iPage = reportProviderStatisMapper.reportOrderList(page,param);
            }
            totallist = reportProviderStatisMapper.reportOrderTotal(param);
        }catch (Exception e){
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        List<ReportProviderStatisDO> doList = null;
        if(iPage!=null&&iPage.getRecords()!=null&&iPage.getRecords().size()>0){
            try {
                List<Map<String, Object>> finalTotallist = totallist;
                doList = iPage.getRecords().stream().map(m->{
                    //处理如果成功率为Null 重新计算成功率
                    if(m.get("successRate")==null){
                        m.put("successRate",0);
                        m.put("totalNumber",0);
                        finalTotallist.stream().forEach(e->{
                            Long totalnum = 0l;
                            switch (query.getType()){
                                case "goods":
                                    if(e.get("goods_id").equals(m.get("goodsId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }
                                    break;
                                case "goodsGroup":
                                    if(e.get("goods_group_id").equals(m.get("goodsGroupId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }

                                    break;
                                case "merchant":
                                    if(e.get("merchant_id").equals(m.get("merchantId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }

                                    break;
                                case "provider":
                                    if(e.get("provider_id").equals(m.get("providerId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }

                                    break;
                            };
                            if(totalnum!=null&&totalnum!=0){
                                Double sucess = Double.valueOf(m.get("successNumber").toString());
                                Double rate = sucess/totalnum.doubleValue();
                                m.put("successRate",rate);
                            }
                        });
                    }
                    //处理如果利润为null 重新计算利润
                    if(m.get("profit")==null){
                        m.put("profit",0);
                        if(m.get("amount")!=null&&m.get("cost")!=null){
                            Double amount = Double.valueOf(m.get("amount").toString());
                            Double cost = Double.valueOf(m.get("cost").toString());
                            Double profit = amount-cost;
                            m.put("profit",profit);
                        }
                    }
                    //如果面额为null 默认给0
                    if(m.get("denomination")==null){
                        m.put("denomination",0);
                    }else{

                    }
                    ReportProviderStatisDO providerStatisDO = MapTool.map2Bean(m,ReportProviderStatisDO.class,true);
                    return providerStatisDO;
                }).collect(Collectors.toList());
            }catch (Exception e){
                e.printStackTrace();
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
                logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
                return result;
            }
        }else if(list!=null&&list.size()>0){
            //如果不分页 处理返回list
            List<Map<String, Object>> finalTotallist = totallist;
            try {
                doList = list.stream().map(m->{
                    if(m.get("successRate")==null){
                        m.put("successRate",0);
                        m.put("totalNumber",0);
                        finalTotallist.stream().forEach(e->{
                            Long totalnum = 0l;
                            switch (query.getType()){
                                case "goods":
                                    if(e.get("goods_id").equals(m.get("goodsId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }
                                    break;
                                case "goodsGroup":
                                    if(e.get("goods_group_id").equals(m.get("goodsGroupId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }

                                    break;
                                case "merchant":
                                    if(e.get("merchant_id").equals(m.get("merchantId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }

                                    break;
                                case "provider":
                                    if(e.get("provider_id").equals(m.get("providerId"))){
                                        totalnum = (Long)e.get("num");
                                        m.put("totalNumber",totalnum);
                                    }

                                    break;
                            };

                            if(totalnum!=null&&totalnum!=0){
                                Double sucess = Double.valueOf(m.get("successNumber").toString());
                                Double rate = sucess/totalnum.doubleValue();
                                m.put("successRate",rate);
                            }
                        });
                    }
                    if(m.get("profit")==null){
                        m.put("profit",0);
                        if(m.get("amount")!=null&&m.get("cost")!=null){
                            Double amount = Double.valueOf(m.get("amount").toString());
                            Double cost = Double.valueOf(m.get("cost").toString());
                            Double profit = amount-cost;
                            m.put("profit",profit);
                        }
                    }
                    if(m.get("denomination")==null){
                        m.put("denomination",0);
                    }
                    ReportProviderStatisDO providerStatisDO = MapTool.map2Bean(m,ReportProviderStatisDO.class,true);
                    return providerStatisDO;
                }).collect(Collectors.toList());
            }catch (Exception e){
                e.printStackTrace();
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
                logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
                return result;
            }
        }
        PageDO<ReportProviderStatisDO> pageDO = new PageDO<>();

        if(iPage!=null){
            pageDO.setCurrentPage(iPage.getCurrent());
            pageDO.setPageCount(iPage.getPages());
            pageDO.setPageSize(iPage.getSize());
            pageDO.setRowCount(iPage.getTotal());
            pageDO.setData(doList);
        }else if(list!=null){
            if(query.getSortField()!=null&&(query.getSortField().equals("totalNumber")||query.getSortField().equals("successRate"))){
                if(doList!=null){
                    if(query.getSortField().equals("totalNumber")){
                        ReportProviderStatisDO tempdo = null;
                        for(int i=0;i<doList.size()-1;i++){
                            for (int j=0;j<doList.size()-1-i;j++){
                                if(query.getOrder().equals("desc")){
                                    if(doList.get(i).getTotalNumber()<doList.get(j).getTotalNumber()){
                                        tempdo = doList.get(i);
                                        doList.set(i,doList.get(j));
                                        doList.set(j,tempdo);
                                        tempdo = null;
                                    }
                                }else{
                                    if(doList.get(i).getTotalNumber()>doList.get(j).getTotalNumber()){
                                        tempdo = doList.get(i);
                                        doList.set(i,doList.get(j));
                                        doList.set(j,tempdo);
                                        tempdo = null;
                                    }
                                }
                            }
                        }
                    }
                    if(query.getSortField().equals("successRate")){
                        ReportProviderStatisDO tempdo = null;
                        for(int i=0;i<doList.size()-1;i++){
                            for (int j=0;j<doList.size()-1-i;j++){
                                if(query.getOrder().equals("desc")){
                                    if(doList.get(i).getSuccessRate()>doList.get(j).getSuccessRate()){
                                        tempdo = doList.get(i);
                                        doList.set(i,doList.get(j));
                                        doList.set(j,tempdo);
                                        tempdo = null;
                                    }
                                }else{
                                    if(doList.get(i).getSuccessRate()<doList.get(j).getSuccessRate()){
                                        tempdo = doList.get(i);
                                        doList.set(i,doList.get(j));
                                        doList.set(j,tempdo);
                                        tempdo = null;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            List<ReportProviderStatisDO> doList2 = new ArrayList<>();
            int startindex = query.getCurrentPage()-1<0?0:(query.getCurrentPage()-1)*query.getPageSize();
            int endindex = doList==null?0:query.getCurrentPage()*query.getPageSize()>doList.size()?doList.size():query.getCurrentPage()*query.getPageSize();
            for(int i=startindex;i<endindex;i++){
                doList2.add(doList.get(i));
            }
            pageDO.setPageCount(doList==null?1:doList.size()%query.getPageSize()==0?(doList.size()/query.getPageSize()):(doList.size()/query.getPageSize())+1);
            pageDO.setCurrentPage(query.getCurrentPage());
            pageDO.setPageSize(query.getPageSize());
            pageDO.setRowCount(list.size());
            pageDO.setData(doList2);
        }

        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);

        return result;
    }

    @Override
    public ResultDO reportOrderByDayDate(ReportProviderStatisQueryDO query) {
        ResultDO result = new ResultSupport();
        Page<Map<String,String>> page = new Page<>(1,40);
        IPage<Map<String,Object>> iPage =null;

        Map<String,Object> param = new HashMap<>();
        if(query.getMerchantId() != null){
            param.put("merchantId",query.getMerchantId());
        }
        if(query.getBusinessClass() != null){
            param.put("businessClass",query.getBusinessClass());
        }
        if(query.getGroupType() != null){
            param.put("groupType",query.getGroupType());
        }
        if(query.getProviderId() != null){
            param.put("providerId",query.getProviderId());
        }
        if(query.getDateType() != null){
            param.put("DateType",query.getDateType());
        }
        if(query.getTime() != null){
            param.put("dayDate",query.getTime());
        }
        //10-21新增筛选
        if(query.getBusinessType()!=null && !query.getBusinessType().equals("")){
            param.put("businessType",query.getBusinessType());
        }


        List<Map<String, Object>> list = null;

        try {
            list = reportProviderStatisMapper.reportOrderByDayDate(page,param);
        }catch (Exception e){
            e.printStackTrace();
            result.setSuccess(false);
            result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
            logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
            return result;
        }

        List<ReportProviderStatisDO> doList = null;
        if(list!=null&&list.size()>0){
            try {
                doList = list.stream().map(m->{
                    ReportProviderStatisDO providerStatisDO = MapTool.map2Bean(m,ReportProviderStatisDO.class,true);
                    return providerStatisDO;
                }).collect(Collectors.toList());
            }catch (Exception e){
                e.printStackTrace();
                result.setSuccess(false);
                result.setErrorCode(ErrorCode.SYSTEM_EXCEPTION);
                logger.debug("error code：" + ErrorCode.SYSTEM_EXCEPTION.getCode() + " msg" + ErrorCode.SYSTEM_EXCEPTION.getMsg());
                return result;
            }
        }

        PageDO<ReportProviderStatisDO> pageDO = new PageDO<>();


//        pageDO.setCurrentPage(iPage.getCurrent());
//        pageDO.setPageCount(iPage.getPages());
//        pageDO.setPageSize(iPage.getSize());
        pageDO.setRowCount(list.size());
        pageDO.setData(doList);


        result.setModel(ResultDO.FIRST_MODEL_KEY, pageDO);

        return result;
    }


    private ReportProviderStatisDO getDomain(ReportProviderStatisEntity entity) {

        //判断房源对象是否为空，为空就返回 空，不为空就进行下面的代码
        if(entity == null) return null;
        ReportProviderStatisDO domain = new ReportProviderStatisDO();

        domain = BeanUtilsExtends.copyProperties(domain, entity) ? domain : null;

        //判断拷贝数据到Dto对象是否成功，如果成功则返回domian，如果不成功就返回空
        return domain;
    }

    private List<ReportProviderStatisDO> getDomainList(List<ReportProviderStatisEntity> list) {
        //创建一个名为dolist的房源do类型的 list集合
        List<ReportProviderStatisDO> doList = new ArrayList<ReportProviderStatisDO>();

        //判断传入的list的集合的size是否大于0
        if(list.size() > 0) {
            //大于0是，遍历list，创建do类型的对象 调用getdomain方法
            for(ReportProviderStatisEntity entity : list) {

                ReportProviderStatisDO domain = this.getDomain(entity);

                //判断得到的domain 是否为空 不为空 就往dolist集合里面添加domian 为空就返回空
                if(domain == null) {
                    return null;
                }
                doList.add(domain);
            }
        } else {
            return null;
        }
        return doList;
    }
}
